package com.lagou.edu.users.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.lagou.edu.code.service.LagouAuthCodeService;
import com.lagou.edu.users.exception.RegisterException;
import com.lagou.edu.users.exception.UserException;
import com.lagou.edu.users.fallback.UserSentinelHandlers;
import com.lagou.edu.users.pojo.LagouToken;
import com.lagou.edu.users.pojo.LagouUser;
import com.lagou.edu.users.pojo.OauthToken;
import com.lagou.edu.users.service.LagouUserService;
import com.lagou.edu.users.utils.RedirecUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

/**
 * 用户API接口：
 * 1、
 */
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private LagouUserService lagouUserService;

    @Reference(retries = 0,check = false)
    private LagouAuthCodeService lagouAuthCodeService;

    /**
     * 用户注册接口，调用验证码服务判断验证码是否正确是否超时，如果正确则保存用户信息
     *
     * @param email email邮箱
     * @param password 密码
     * @param code 验证码
     * @return true：成功，false：失败
     */
    @GetMapping("/register/{email}/{password}/{code}")
    public Boolean register(@PathVariable(name = "email") String email,
                            @PathVariable(name = "password") String password,
                            @PathVariable(name = "code") String code,
                            HttpServletRequest request,
                            HttpServletResponse response) throws IOException {
        // 1、判断验证码是否正确，0正确1错误2超时
        Integer validate = lagouAuthCodeService.validate(email, code);
        if (validate != 0){
            throw new RegisterException("验证码错误。");
        }

        // 2、如果验证码正确，保存用户信息
        if (StringUtils.isEmpty(password)){
            throw new RegisterException("请输入密码。");
        }
        Integer checkEmail = lagouUserService.getCheckEmail(email);
        // 2、判断
        if (checkEmail != 0){
            throw new RegisterException("邮箱已被注册，请切换其它邮箱。");
        }
        LagouUser lagouUser = new LagouUser();
        lagouUser.setEmail(email);
        lagouUser.setPassword(password);
        lagouUser.setCreatetime(new Date(System.currentTimeMillis()));
        lagouUserService.saveUser(lagouUser);
        // 3、注册成功跳转到登录页面
        loginHandle(request,response,email,password);
        return true;
    }

    /**
     * 判断是否注册，这里根据邮箱查询统计数量，如果为0表示未注册，其余表示已注册
     *
     * @param email 邮箱
     * @return true：已经注册，false表示未注册
     */
    @GetMapping("/isRegistered/{email}")
    public Boolean isRegistered(@PathVariable(name = "email") String email){
        // 1、查询邮箱的统计计数
        Integer checkEmail = lagouUserService.getCheckEmail(email);
        // 2、判断
        if (checkEmail == 0){
            return true;
        }
        return false;
    }

    /**
     * 用户登录
     * 1、验证密码合法性
     * 2、根据用户名和密码生成token
     * 3、并且将token存入数据库
     * 4、写入cookie中
     * 5、返回邮箱地址，重定向到欢迎页
     *
     * @param email
     * @param password
     */
    @GetMapping("/login/{email}/{password}")
    public String login(@PathVariable(name = "email") String email,
                      @PathVariable(name = "password") String password,
                        HttpServletRequest request,
                        HttpServletResponse response) throws IOException {
//        // 1、验证密码合法性
//        LagouUser lagouUser = lagouUserService.getLagouUserByEmail(email);
//        if (lagouUser == null){
//            // 用户不存在
//            throw new UserException("用户不存在。");
//        }
//        if (!lagouUser.getPassword().equals(password)) {
//            // 密码错误
//            throw new UserException("用户名密码错误。");
//        }

        loginHandle(request,response,email,password);

        return email;
    }

    /**
     * 登录系统处理
     *
     * @param response
     * @param email
     * @param password
     * @throws IOException
     */
    private void loginHandle(HttpServletRequest request,HttpServletResponse response,String email,String password) throws IOException {
        //根据用户名和密码生成token
        OauthToken token = lagouUserService.generateToken(email,password);
        //写入cookie中
        Cookie cookie = new Cookie("lagou_token",token.getAccess_token());
        cookie.setPath("/");
        cookie.setMaxAge(token.getExpires_in());
        response.addCookie(cookie);
        Cookie cookieRefresh = new Cookie("refresh_token",token.getRefresh_token());
        cookieRefresh.setPath("/");
        cookieRefresh.setMaxAge(Integer.MAX_VALUE);
        response.addCookie(cookieRefresh);
        RedirecUtil.redirect(request,response,"http://www.test.com/static/welcome.html");
    }

    /**
     * 根据token查询用户登录邮箱接口
     * @param token
     * @return 邮箱
     */
    @GetMapping("/info/{token}")
    public String info(@PathVariable("token") String token){
        String principal = (String) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        return principal;
    }

    /**
     * 刷新token
     * @param request
     * @param response
     * @return
     */
    @GetMapping("/refresh")
    public boolean refreshToken(HttpServletRequest request,HttpServletResponse response){
        String refresh_token = request.getHeader("refreshtoken");
        OauthToken token = lagouUserService.refreshToken(refresh_token);
        //写入cookie中
        Cookie cookie = new Cookie("lagou_token",token.getAccess_token());
        cookie.setPath("/");
        cookie.setMaxAge(token.getExpires_in());
        response.addCookie(cookie);
        return true;
    }

    @GetMapping("/test")
    @SentinelResource(value = "test",blockHandlerClass = UserSentinelHandlers.class,
            blockHandler = "handleTestException",fallbackClass =UserSentinelHandlers.class,
            fallback = "handleTestError")
    public String test(){
        return lagouAuthCodeService.generateCode();
    }

}
